#include "log.hpp"
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

class TcpClient
{
public:
    TcpClient(std::string server_ip, int server_port)
        : _sock(-1), _server_port(server_port), _server_ip(server_ip)
    {
    }

    bool InitClient()
    {
        // 创建套接字
        _sock = socket(AF_INET, SOCK_STREAM, 0);
        if (_sock < 0)
        {
            logMessage(ERROR, "client socket create error");
            exit(2);
        }
    }
    void Request()
    {
        // 三、客户端做出反应
        std::string msg;
        char buffer[1024];
        while (true)
        {
            // 1.客户端输入数据
            std::cout << "please Enter# ";
            getline(std::cin, msg);

            // 2.将数据写到客户端自己的套接字里面，后续套接字会将数据通过网络发送到指定IP指定的端口号处，然后服务端的服务套接字会获取到数据
            write(_sock, msg.c_str(), msg.size());

            // 3.接收服务端响应回来的数据
            ssize_t size = read(_sock, buffer, sizeof(buffer) - 1);
            if (size > 0)
            {
                buffer[size] = '\0';
                std::cout << "server echo# " << buffer << std::endl;
            }
            else if (size == 0)
            {
                std::cout << "server close! " << std::endl;
                break;
            }
            else
            {
                std::cerr << "read error! " << std::endl;
                break;
            }
        }
    }
    void Start()
    {
        struct sockaddr_in peer;
        bzero(&peer, sizeof(peer));
        peer.sin_family = AF_INET;
        peer.sin_port = htons(_server_port);                  // unsigned short int 转 unsgined short int
        peer.sin_addr.s_addr = inet_addr(_server_ip.c_str()); /// 字符串char*类型 转 unsigned int
        if (connect(_sock, (struct sockaddr *)&peer, sizeof(peer) )== 0)
        {
            // connect success
            logMessage(NORMAL, "client connect success...");
            Request();
        }
        else
        {
            // connect error
            logMessage(ERROR, "client connect error");
            exit(3);
        }
    }

    ~TcpClient()
    {
        if (_sock >= 0)
        {
            close(_sock);
        }
    }

private:
    int _sock;              // 文件描述符
    int _server_port;       // 服务端端口号（客户端要向哪一个端口号发送数据、接收哪一个端口号的数据）
    std::string _server_ip; // 服务端IP地址（客户端要向哪一个地址发送数据、接收哪一个地址的数据）
};